import axios, { AxiosInstance, AxiosRequestConfig } from "axios"

export interface ResponseData<T> {
  code: number
  data?: T
  msg?: string
}

export default new (class HttpRequest {
  public baseURL = import.meta.env.DEV ? "/api" : " /"
  public timeout = 3000
  public request(customOptions: AxiosRequestConfig) {
    const instance = axios.create()
    const options = this.mergeOptions(customOptions)
    this.setInterceptors(instance)
    return instance(options)
  }
  protected mergeOptions(options: AxiosRequestConfig) {
    return Object.assign(
      {
        baseURL: this.baseURL,
        timeout: this.timeout
      },
      options
    )
  }
  protected setInterceptors(instance: AxiosInstance) {
    instance.interceptors.request.use(
      (config) => {
        // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
        config.headers!["token"] = "beare token"
        return config
      },
      (err) => Promise.reject(err)
    )
    instance.interceptors.response.use(
      (res) => {
        const { code } = res.data
        if (code != 0) {
          return Promise.reject(res)
        }
        // 业务状态扩展 401 402 403
        return res
      },
      (err) => Promise.reject(err)
    )
  }
  public get<T>(url: string, data: unknown): Promise<ResponseData<T>> {
    return this.request({ method: "get", url, params: data })
      .then((res) => {
        return Promise.resolve(res.data)
      })
      .catch((err) => {
        return Promise.reject(err)
      })
  }
  public post<T>(url: string, data: unknown): Promise<ResponseData<T>> {
    return this.request({ method: "post", url, data })
      .then((res) => Promise.resolve(res.data))
      .catch((err) => Promise.reject(err))
  }
})()
